package string;

import java.util.Stack;

/**
 * @Author Yi Jun jie
 * @Date 2021/3/1 19:32
 * 面试题 16.26. 计算器
 */
public class LeetCode1626 {
    public static void main(String[] args) {
        String s = "42";
        System.out.println(new Solution1626().calculate(s));
    }
}

/**
 * 1. 如果碰到数字， 则把数字入栈
 * 2. 如果碰到空格， 则继续下一步
 * 3. 如果碰到 '+' '-' '*' '/', 则查找下一个数字num
 *     A.如果是'+', 下一个数字num直接入栈
 *     B.如果是'-'，-num入栈
 *     C.如果是'*', num = stack.pop() * num, 入栈
 *     D.如果是'/', num = stack.pop() / num, 入栈
 * 4. 最后，把栈里的数相加就是结果
 */
class Solution1626 {
    public int calculate(String s) {
        if (s == null || s.length() == 0) return 0;
        s = s.replace(" ", "");
        Stack<Integer> num = new Stack<>();
        int n = 0;
        char op = '+';
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            //判断是否是数字
            if (Character.isDigit(c)) {
                //c - '0' 的作用是将 c 从字符转化为数字 n*10 是用来解决 42 这种带十位的不是个位数的数字
                n = n * 10 + (c - '0');
            }
            //isDigit 方法确定指定字符是否为数字
            if (!Character.isDigit(c) || i == s.length() - 1) {
                int pre;
                switch (op) {
                    case '+':
                        num.push(n);
                        break;
                    case '-':
                        num.push(-n); //负数的话以负数的值来入栈
                        break;
                    case '*':
                        pre = num.pop(); //从栈里面获取上一个数字
                        num.push(pre * n); //将算式中 * 法的值算出来再加入栈中
                        break;
                    case '/':
                        pre = num.pop(); //从栈里面获取上一个数字
                        num.push(pre / n); //将算式中 / 法的值算出来再加入栈中
                        break;
                }
                op = c;
                // 这里只有在对应字符不为数字的时候才会重置为 0
                n = 0;
            }
        }
//        int res = 0;
        //将栈里卖的数据都加起来就是答案
//        while (!num.isEmpty()) {
//            res += num.pop();
//        }
        Integer res = num.stream().parallel().reduce(0, Integer::sum);

        return res;
    }
}
